/**
 * Test de una aplicacion cliente de metainformacion
 * y emisora de eventos
 *
 * @date 15/10/2008
 * @author Carlos Rodriguez Dominguez
 */

#include <stdlib.h>
#include <stdio.h>

#include "collaboration_subsystem.h"

//test de un objeto que soporta eventos
class test_object : public ListeningObject {
private:
	int x;
	int y;
	
public:
	test_object() : ListeningObject()
	{
		x = 0;
		y = 0;
	}
	
	void changeXY(int xx, int yy)
	{
		x = xx;
		y = yy;
		
		PairEvent* ev = new PairEvent();
		ev->set_x(xx);
		ev->set_y(yy);
		
		collaboration::EVENT_HANDLER->push(ev);
		
		delete ev;
	}
};

//test de una clase listener
class test_listener : public EventListener {
public:
	test_listener()
	{
		
	}
	
	~test_listener()
	{
		
	}
	
	bool check_event(Event* evt)
	{
		if (evt->get_type() == PAIR_EVENT_TYPE)
		{
			return true;
		}
		else return false;
	}
	
	void action(void* receiver, Event* data)
	{
		PairEvent* ev = (PairEvent*)data;
		
		printf("recibido: %d, %d \n", (int)ev->get_x(), (int)ev->get_y());
	}
	
	const char* name()
	{
		return "test_listener";
	}
};

int main(int argc, char** argv)
{	
	if (!collaboration::setup_environment(argc, argv))
	{
		printf("error al inicializar el sistema de colaboracion\n");
		exit(1);
	}
	
	//////////// TEST DE ACCESO A METAINFORMACION ///////////////////
	
	printf("Aplicaciones:\n");
	collaboration::ListOfApplications* ls = collaboration::get_applications();
	int len = ls->length();
	for (int i=0; i<len; i++)
	{
		printf("%s\n", (char*)(*ls)[i].name);
	}
	
	printf("Usuarios de la primera aplicacion:\n");
	collaboration::ListOfUsers* lu = collaboration::get_users((*ls)[0].name);
	len = lu->length();
	for (int i=0; i<len; i++)
	{
		printf("%s\n", (char*)(*lu)[i].name);
	}
	
	collaboration::setup_MIServiceConnector((*ls)[0].name, "User", "clave");
	
	printf("Usuarios conectados:\n");
	lu = collaboration::MI_SERVICE_CONNECTOR->connected_users();
	len = lu->length();
	for (int i=0; i<len; i++)
		printf("%s\n",  (char*)(*lu)[i].name);
	
	printf("Haciendo login\n");
	collaboration::MIConnection* mi_conn = collaboration::MI_SERVICE_CONNECTOR->login();
	
	printf("es administridador: %s\n", collaboration::MI_SERVICE_CONNECTOR->admin()?"true":"false");
	printf("Mensaje de error: %s\n", (char*)mi_conn->error_message);
	
	if (strcmp(mi_conn->error_message, "") != 0)
	{
		collaboration::MIUser* user = collaboration::MI_SERVICE_CONNECTOR->user_info(); 
		printf("tiempo ultimo de actualizacion: %ld\n", (long)user->last_time_updated);
		long t = time(0);
		printf("tiempo actual: %ld\n", t);
		printf("falta %ld tiempo para auto-desconexion\n", t- (long)user->last_time_updated);
		collaboration::MI_SERVICE_CONNECTOR->disconnect_user();
	}
	
	char* role = collaboration::MI_SERVICE_CONNECTOR->connect_user();
	printf("Conexion de usuario, rol asignado: %s\n", role);
	
	//////////  TEST DE OBJETO EMISOR/RECEPTOR DE EVENTOS //////////
	test_object* dobj = new test_object();
	test_listener* listener = new test_listener();
	dobj->addEventListener(listener);
	
	collaboration::EVENT_HANDLER->register_object(dobj);
	
	printf("\n\nPrueba de componente distribuido: \n");
	int x,y;
	while(1){
		printf("introduzca numero para enviar evento: ");
		scanf("%d %d", &x, &y);
		
		dobj->changeXY(x, y);
		
	} //bucle infinito para evitar el fin del cliente
	
	collaboration::shutdown_MIServiceConnector();
	collaboration::shutdown_environment();
	
	return 0;
}
